package com.bytz.modules.cms.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bytz.common.exception.BytzBootException;
import com.bytz.common.system.base.service.impl.AbstractCrudService;
import com.bytz.common.system.query.QueryGenerator;
import com.bytz.common.util.mentity.EntityMergeInfoV2;
import com.bytz.common.util.mentity.util.MergeEntityOptions;
import com.bytz.common.util.mentity.util.MergeEntityUtil;
import com.bytz.modules.cms.common.util.ExcelUtil;
import com.bytz.modules.cms.domain.util.PriceComputerUtil;
import com.bytz.modules.cms.product.entity.Product;
import com.bytz.modules.cms.product.entity.ProductHierarchy;
import com.bytz.modules.cms.product.mapper.ProductHierarchyMapper;
import com.bytz.modules.cms.product.service.IAdminProductHierarchyService;
import com.bytz.modules.cms.product.service.IProductService;
import com.bytz.modules.cms.productLine.entity.ProductLine;
import com.bytz.modules.cms.productLine.service.IProductLineService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AdminProductHierarchyService extends AbstractCrudService<ProductHierarchyMapper, ProductHierarchy, ProductHierarchy> implements IAdminProductHierarchyService {

    @Autowired
    private IProductLineService productLineService;

    @Autowired
    @Lazy
    private IProductService productService;

    @Override
    protected ProductHierarchy insertSaveObject(ProductHierarchy saveRo) {
        save(saveRo);
        return saveRo;
    }

    @Override
    protected ProductHierarchy updateSaveObject(ProductHierarchy saveRo) {
        updateById(saveRo);
        return saveRo;
    }

    @Override
    protected ProductHierarchy saveOthers(ProductHierarchy saveRo) {
        return null;
    }

    @Override
    protected boolean deleteEntity(ProductHierarchy entity) {
        return removeById(entity.getId());
    }

    @Override
    protected void deleteOthers(ProductHierarchy entity) {

    }

    @Override
    public IPage<ProductHierarchy> queryPage(Page<ProductHierarchy> page, ProductHierarchy productHierarchy, Map<String, String[]> parameterMap) {
        QueryWrapper<ProductHierarchy> queryWrapper = QueryGenerator.initQueryWrapper(productHierarchy, parameterMap);
        return page(page, queryWrapper);
    }

    @Override
    public void export(ProductHierarchy productHierarchy, Map<String, String[]> parameterMap, HttpServletResponse response) throws IOException {
        QueryWrapper<ProductHierarchy> queryWrapper = QueryGenerator.initQueryWrapper(productHierarchy, parameterMap);
        List<ProductHierarchy> list = list(queryWrapper);
        list.forEach(hierarchy -> {
            hierarchy.setPrepayRatio(hierarchy.getPrepayRatio().multiply(BigDecimal.valueOf(100)));
        });
        ExcelUtil.export("商品分类", ProductHierarchy.class, response, list);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<ProductHierarchy> importExcel(List<ProductHierarchy> models) {

        // 检查导入会不会影响到商品
        List<String> hierarchyNumbers = models.stream().map(ProductHierarchy::getHierarchyNumber).collect(Collectors.toList());
        List<Product> influenceProducts = productService.hasHierarchyExclude(hierarchyNumbers);
        if (influenceProducts.size() > 0) {
            throw new BytzBootException("下列Hierarchy number" +
                    influenceProducts.stream().map(Product::getHierarchyNumber).collect(Collectors.toSet()) +
                    "已在商品中被定义，但不存在于导入列表，无法导入");
        }

        Map<String, ProductLine> productLineMap = productLineService.list().stream().collect(Collectors.toMap(ProductLine::getProductLineCode, t -> t));

        models.forEach(hierarchy -> {
            ProductLine productLine = productLineMap.get(hierarchy.getProductLineCode());
            if (productLine == null) {
                throw new BytzBootException(String.format("找不到产品线【%s】", hierarchy.getProductLineCode()));
            }
            hierarchy.setProductLineId(productLine.getId());
            hierarchy.setPrepayRatio(PriceComputerUtil.divide(hierarchy.getPrepayRatio(), BigDecimal.valueOf(100)));
        });

        EntityMergeInfoV2<ProductHierarchy> mergeInfo = MergeEntityUtil.calculateEntityMergeInfo(
                models,
                list(),
                MergeEntityOptions.<ProductHierarchy>builder().keyExtractor(ProductHierarchy::getHierarchyNumber).build()
        );
        return MergeEntityUtil.doDbMerge(mergeInfo, this);
    }
}
